#!/usr/bin/env python
# -*- coding: utf-8 -*-

import sys
import time

import serial
import serial.tools.list_ports
from loguru import logger

class SerialPortCom(object):
    def __init__(self):
        super().__init__()
        # self.init()
        self.ser = serial.Serial()
        logger.debug("SerialPortCom __init__ end. Create an instance of Serial successfully.")

    # def init(self):
    #     self.time_start = time.time()
    #     self.time_end = time.time()
    #     # 定时发送数据
    #     self.timer_send = QTimer()

    # 串口检测, 返回所有串口设备
    def port_check(self):
        # 检测所有存在的串口，将信息存储在字典中
        self.Com_Dict = {}
        port_list = list(serial.tools.list_ports.comports())
        for port in port_list:
            self.Com_Dict["%s" % port[0]] = "%s" % port[1]
        
        if len(self.Com_Dict) == 0:
            logger.warning("there is no serial port available.")

        return self.Com_Dict

    # # 串口信息
    # def port_imf(self):
    #     # 显示选定的串口的详细信息
    #     imf_s = self.s1__box_2.currentText()
    #     if imf_s != "":
    #         self.state_label.setText(self.Com_Dict[self.s1__box_2.currentText()])

    # 打开串口，并设置串口通信的一些参数
    # 
    def port_open(self, port, baudrate, bytesize, stopbits, parity):
        self.ser.port = port
        self.ser.baudrate = baudrate
        self.ser.bytesize = bytesize
        self.ser.stopbits = stopbits
        self.ser.parity = parity

        if self.ser.isOpen():
            return True

        try:
            self.ser.open()
        except:
            logger.exception("Fail to open the serial port: {}", port)
            return False

        if self.ser.isOpen():
            logger.debug("the serial port {} is opened successfully.", port)
            return True
        else:
            logger.error("the serial port {} is not opened.", port)
            return False

    # 关闭串口
    def port_close(self):
        try:
            self.ser.close()
            logger.info("Close the serial port: {} successfully.", self.ser.port)
        except:
            logger.exception("Fail to close the serial port: {}", self.ser.port)


    # 发送数据, Mode = ASCII或者HEX, 
    def data_send(self, mode, data):
        if self.ser.isOpen():
            if data != "":
                # 非空字符串
                if mode == "HEX":
                    # hex发送
                    data = data.strip()
                    send_list = []
                    while data != '':
                        try:
                            num = int(data[0:2], 16)
                        except ValueError:
                            logger.exception("wrong data, 请输入十六进制数据，以空格分开!")
                            return None
                        data = data[2:].strip()
                        send_list.append(num)
                    data = bytes(send_list)
                else:
                    # ascii发送
                    data = (data + '\r\n').encode('utf-8')

                num = self.ser.write(data)
                logger.debug("send data to serial port successfully with mode {}", mode)
                return num
        else:
            pass

    # 接收数据
    def data_receive(self, mode):
        try:
            num = self.ser.inWaiting()
        except:
            self.port_close()
            logger.exception("failed to receive data and close the serial port.")
            return None

        if num > 0:
            data = self.ser.read(num)
            logger.debug("receive data successfully. data length is {}", num)
            num = len(data)
            # hex显示
            if mode == "HEX":
                out_s = ''
                for i in range(0, len(data)):
                    out_s = out_s + '{:02X}'.format(data[i]) + ' '
                return out_s
            else:
                # 串口接收到的字符串为b'123',要转化成unicode字符串才能输出到窗口中去
                return data.decode('iso-8859-1')
        else:
            return ""


if __name__ == '__main__':
    serialport = SerialPortCom()
    com_dict = serialport.port_check()

    if len(com_dict) != 0:
        port = list(com_dict.keys())[0]
        baudrate = 115200
        bytesize = 8
        stopbits = 1
        parity = "N"
        isopen = serialport.port_open(port, baudrate, bytesize, stopbits, parity)
        if isopen:
            send_data = "AT"
            data_send_len = serialport.data_send("ASCII", send_data)
            if not (len(send_data) + 2 == data_send_len):
                print("Send data failed")

            time.sleep(0.02)
            receive_data = serialport.data_receive("ASCII")
            if receive_data.endswith("OK"):
                print("Success \n")
            print(receive_data)

        
        serialport.port_close()

